package com.hao.sys.config;

import com.hao.shirojwt.util.ResultEnum;
import com.hao.shirojwt.util.json.JsonService;
import com.hao.shirojwt.util.response.BaseResponse;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Aspect
@Component
@Slf4j
public class WebLogAspect {
    @Resource
    private JsonService jsonService;

    @Pointcut("execution(* com.hao.sys..controller..*.*(..))")
    //@Pointcut("execution(* com.hao.sys..*Controller.*(..))")
    public void controllerPointCut(){
    }
    @Pointcut("execution(* com.hao.sys..provide..*.*(..))")
    public void providePointCut(){
    }


    @Before("controllerPointCut() || providePointCut()")
    public void doBefore(JoinPoint joinPoint) {
        String classMethod = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName();

        String paramsName = jsonService.toJSONString(((MethodSignature)joinPoint.getSignature()).getParameterNames());
        String paramsValue = jsonService.toJSONString(joinPoint.getArgs());

        log.info(classMethod + ": 请求参数名称: " + paramsName);
        log.info(classMethod + ": 请求参数值: " + paramsValue);
    }

    @AfterReturning(returning = "response", pointcut = "controllerPointCut() || providePointCut()")
    public void doAfterReturning(Object response) throws Throwable {
        if (response != null) {
            if (response instanceof BaseResponse) {
                BaseResponse baseResponse = (BaseResponse) response;
                if (ResultEnum.SUCCESS.getCode().equals(baseResponse.getCode())) {
                    log.debug("response parameter : " + jsonService.toJSONString(response));
                }else{
                    log.error("response parameter : " + jsonService.toJSONString(response));
                }
            }
        }
    }

    @AfterThrowing(pointcut = "controllerPointCut() || providePointCut()", throwing = "e")
    public void doAfterThrowing(Exception e) {
        log.info("Controller执行异常：" + e.getMessage());
    }

    /**
     * 声明环绕通知
     */
    @Around("controllerPointCut() || providePointCut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        long begin = System.currentTimeMillis();
        log.info("**************************************************");
        log.info("Controller执行开始 =====>");

        Object obj = null;
        try{
            obj = pjp.proceed();

        }catch (Exception e){
            log.error(e.getMessage(), e);
        }

        long end = System.currentTimeMillis();
        String classMethod = pjp.getTarget().getClass().getName() + "." + pjp.getSignature().getName();
        log.info("Controller执行结束耗时：{}毫秒，方法：{} <=====", (end - begin), classMethod);

        return obj;
    }
}
